package com.vr.cloudpicture.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vr.cloudpicture.enums.SpaceRoleEnum;
import com.vr.cloudpicture.exception.ErrorCode;
import com.vr.cloudpicture.exception.ThrowUtils;
import com.vr.cloudpicture.mapper.SpaceUserMapper;
import com.vr.cloudpicture.model.dto.DeleteRequest;
import com.vr.cloudpicture.model.dto.spaceuser.SpaceUserAddRequest;
import com.vr.cloudpicture.model.dto.spaceuser.SpaceUserEditRequest;
import com.vr.cloudpicture.model.dto.spaceuser.SpaceUserQueryRequest;
import com.vr.cloudpicture.model.dto.user.UserLogin;
import com.vr.cloudpicture.model.entity.Space;
import com.vr.cloudpicture.model.entity.SpaceUser;
import com.vr.cloudpicture.model.entity.User;
import com.vr.cloudpicture.model.vo.SpaceUserVO;
import com.vr.cloudpicture.model.vo.SpaceVO;
import com.vr.cloudpicture.model.vo.UserVO;
import com.vr.cloudpicture.service.ISpaceService;
import com.vr.cloudpicture.service.ISpaceUserService;
import com.vr.cloudpicture.service.IUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author hzh
 * @description 针对表【space_user(空间用户关联)】的数据库操作Service实现
 * @createDate 2025-05-26 19:28:52
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SpaceUserServiceImpl extends ServiceImpl<SpaceUserMapper, SpaceUser> implements ISpaceUserService {
    private final IUserService userService;
    private final ISpaceService spaceService;
    private final SpaceUserMapper spaceUserMapper;

    @Override
    public SpaceUser getSpaceUser(SpaceUserQueryRequest spaceUserQueryRequest) {
        ThrowUtils.throwIf(spaceUserQueryRequest == null, ErrorCode.PARAMS_ERROR);
        Long spaceId = spaceUserQueryRequest.getSpaceId();
        Long userId = spaceUserQueryRequest.getUserId();
        LambdaQueryWrapper<SpaceUser> queryWrapper = this.getQueryWrapper(spaceUserQueryRequest);
        ThrowUtils.throwIf(ObjUtil.hasEmpty(spaceId, userId), ErrorCode.PARAMS_ERROR);
        SpaceUser spaceUser = spaceUserMapper.selectOne(queryWrapper);
        ThrowUtils.throwIf(spaceUser == null, ErrorCode.NOT_FOUND_ERROR);
        return spaceUser;
    }

    @Override
    public List<SpaceUserVO> listSpaceUserVO(SpaceUserQueryRequest spaceQueryRequest) {
        ThrowUtils.throwIf(spaceQueryRequest == null, ErrorCode.PARAMS_ERROR);
        LambdaQueryWrapper<SpaceUser> queryWrapper = this.getQueryWrapper(spaceQueryRequest);
        List<SpaceUser> spaceUserList = spaceUserMapper.selectList(queryWrapper);
        if (spaceUserList == null || spaceUserList.isEmpty()) {
            return Collections.emptyList();
        }
        // 批量获取关联的用户和空间信息
        // 1.拿到关联的用户id和空间id列表
        Set<Long> userIdList = new HashSet<>();
        Set<Long> spaceIdList = new HashSet<>();
        spaceUserList.forEach(spaceUser -> {
            userIdList.add(spaceUser.getUserId());
            spaceIdList.add(spaceUser.getSpaceId());
        });
        // 2.根据id批量查询用户和空间信息
        List<User> userList = userService.listByIds(userIdList);
        List<Space> spaceList = spaceService.listByIds(spaceIdList);
        // 3.构建map映射,一对一的关系
        Map<Long, UserVO> userIdUserVOMap = userList.stream()
                // 封装成VO
                .map(UserVO::objToVO)
                .collect(Collectors.toMap(UserVO::getId, userVO -> userVO));
        Map<Long, SpaceVO> spaceIdSpaceVOMap = spaceList.stream()
                // 封装成VO
                .map(SpaceVO::objToVO)
                .collect(Collectors.toMap(SpaceVO::getId, spaceVO -> spaceVO));
        // 转换成Vo列表
        List<SpaceUserVO> spaceUserVOList = spaceUserList.stream().map(SpaceUserVO::objToVO).collect(Collectors.toList());
        spaceUserVOList.forEach(spaceUserVO -> {
            spaceUserVO.setUser(userIdUserVOMap.getOrDefault(spaceUserVO.getUserId(),null));
            spaceUserVO.setSpace(spaceIdSpaceVOMap.getOrDefault(spaceUserVO.getSpaceId(),null));
        });
        return spaceUserVOList;
    }

    @Override
    public Boolean editSpaceUser(SpaceUserEditRequest spaceUserEditRequest, UserLogin loginUser) {
        // TODO只有空间管理员或者本人可以操作
        ThrowUtils.throwIf(spaceUserEditRequest == null || spaceUserEditRequest.getId()<=0, ErrorCode.PARAMS_ERROR);
        SpaceUser spaceUser = BeanUtil.toBean(spaceUserEditRequest, SpaceUser.class);
        // 校验信息
        validSpaceUser(spaceUser, false);
        SpaceUser oldSpaceUser = spaceUserMapper.selectById(spaceUser.getId());
        ThrowUtils.throwIf(oldSpaceUser == null, ErrorCode.NOT_FOUND_ERROR);
        // 操作数据库
        return spaceUserMapper.updateById(spaceUser) > 0;
    }

    @Override
    public Long addSpaceUser(SpaceUserAddRequest spaceUserAddRequest, UserLogin loginUser) {
        ThrowUtils.throwIf(spaceUserAddRequest == null, ErrorCode.PARAMS_ERROR);
        SpaceUser spaceUser = BeanUtil.toBean(spaceUserAddRequest, SpaceUser.class);
        validSpaceUser(spaceUser, true);
        // 数据库操作
        int insert = spaceUserMapper.insert(spaceUser);
        ThrowUtils.throwIf(insert <= 0, ErrorCode.OPERATION_ERROR);
        return spaceUser.getId();
    }

    @Override
    public Boolean deleteSpaceUser(DeleteRequest deleteRequest, UserLogin loginUser) {
        // TODO只有空间管理员或者本人可以操作
        ThrowUtils.throwIf(deleteRequest == null || deleteRequest.getId()<=0, ErrorCode.PARAMS_ERROR);
        SpaceUser oldSpaceUser = spaceUserMapper.selectById(deleteRequest.getId());
        ThrowUtils.throwIf(oldSpaceUser == null, ErrorCode.NOT_FOUND_ERROR);
        return spaceUserMapper.deleteById(deleteRequest.getId()) > 0;
    }

    @Override
    public void validSpaceUser(SpaceUser spaceUser, boolean add) {
        ThrowUtils.throwIf(spaceUser == null, ErrorCode.PARAMS_ERROR);
        Long userId = spaceUser.getUserId();
        Long spaceId = spaceUser.getSpaceId();
        if (add) {
            ThrowUtils.throwIf(ObjUtil.hasEmpty(userId, spaceId), ErrorCode.PARAMS_ERROR);
            // 校验关联用户是否存在
            User user = userService.getById(userId);
            ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR, "用户不存在");
            // 校验关联空间是否存在
            Space space = spaceService.getById(spaceId);
            ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在");
        }
        // 校验空间权限
        String spaceRole = spaceUser.getSpaceRole();
        SpaceRoleEnum spaceRoleEnum = SpaceRoleEnum.getEnumByValue(spaceRole);
        ThrowUtils.throwIf(spaceRole != null && spaceRoleEnum == null, ErrorCode.PARAMS_ERROR, "空间角色不存在");
    }

    @Override
    public LambdaQueryWrapper<SpaceUser> getQueryWrapper(SpaceUserQueryRequest spaceUserQueryRequest) {
        LambdaQueryWrapper<SpaceUser> queryWrapper = new LambdaQueryWrapper<>();
        if (spaceUserQueryRequest == null) {
            return queryWrapper;
        }
        Long id = spaceUserQueryRequest.getId();
        Long spaceId = spaceUserQueryRequest.getSpaceId();
        Long userId = spaceUserQueryRequest.getUserId();
        String spaceRole = spaceUserQueryRequest.getSpaceRole();
        queryWrapper.eq(ObjUtil.isNotEmpty(id), SpaceUser::getId, id);
        queryWrapper.eq(ObjUtil.isNotEmpty(spaceId), SpaceUser::getSpaceId, spaceId);
        queryWrapper.eq(ObjUtil.isNotEmpty(userId), SpaceUser::getUserId, userId);
        queryWrapper.eq(StrUtil.isNotEmpty(spaceRole), SpaceUser::getSpaceRole, spaceRole);
        return queryWrapper;
    }
}




